home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -screenplay- / shareware / warpquake / warpquakesrc / gl_screen.c < prev    next >
C/C++ Source or Header  |  2000-02-29  |  18KB  |  924 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. // screen.c -- master for refresh, status bar, console, chat, notify, etc
  22.  
  23. #include "quakedef.h"
  24.  
  25. /*
  26.  
  27. background clear
  28. rendering
  29. turtle/net/ram icons
  30. sbar
  31. centerprint / slow centerprint
  32. notify lines
  33. intermission / finale overlay
  34. loading plaque
  35. console
  36. menu
  37.  
  38. required background clears
  39. required update regions
  40.  
  41.  
  42. syncronous draw mode or async
  43. One off screen buffer, with updates either copied or xblited
  44. Need to double buffer?
  45.  
  46.  
  47. async draw will require the refresh area to be cleared, because it will be
  48. xblited, but sync draw can just ignore it.
  49.  
  50. sync
  51. draw
  52.  
  53. CenterPrint ()
  54. SlowPrint ()
  55. Screen_Update ();
  56. Con_Printf ();
  57.  
  58. net 
  59. turn off messages option
  60.  
  61. the refresh is allways rendered, unless the console is full screen
  62.  
  63.  
  64. console is:
  65.     notify lines
  66.     half
  67.     full
  68.     
  69.  
  70. */
  71.  
  72.  
  73. int            glx, gly, glwidth, glheight;
  74.  
  75. // only the refresh window will be updated unless these variables are flagged 
  76. int            scr_copytop;
  77. int            scr_copyeverything;
  78.  
  79. float        scr_con_current;
  80. float        scr_conlines;        // lines of console to display
  81.  
  82. float        oldscreensize, oldfov;
  83. cvar_t        scr_viewsize = {"viewsize","100", true};
  84. cvar_t        scr_fov = {"fov","90"};    // 10 - 170
  85. cvar_t        scr_conspeed = {"scr_conspeed","300"};
  86. cvar_t        scr_centertime = {"scr_centertime","2"};
  87. cvar_t        scr_showram = {"showram","1"};
  88. cvar_t        scr_showturtle = {"showturtle","0"};
  89. cvar_t        scr_showpause = {"showpause","1"};
  90. cvar_t        scr_printspeed = {"scr_printspeed","8"};
  91. cvar_t        gl_triplebuffer = {"gl_triplebuffer", "1", true };
  92.  
  93. extern    cvar_t    crosshair;
  94.  
  95. qboolean    scr_initialized;        // ready to draw
  96.  
  97. qpic_t        *scr_ram;
  98. qpic_t        *scr_net;
  99. qpic_t        *scr_turtle;
  100.  
  101. int            scr_fullupdate;
  102.  
  103. int            clearconsole;
  104. int            clearnotify;
  105.  
  106. int            sb_lines;
  107.  
  108. viddef_t    vid;                // global video state
  109.  
  110. vrect_t        scr_vrect;
  111.  
  112. qboolean    scr_disabled_for_loading;
  113. qboolean    scr_drawloading;
  114. float        scr_disabled_time;
  115.  
  116. qboolean    block_drawing;
  117.  
  118. void SCR_ScreenShot_f (void);
  119.  
  120. /*
  121. ===============================================================================
  122.  
  123. CENTER PRINTING
  124.  
  125. ===============================================================================
  126. */
  127.  
  128. char        scr_centerstring[1024];
  129. float        scr_centertime_start;    // for slow victory printing
  130. float        scr_centertime_off;
  131. int            scr_center_lines;
  132. int            scr_erase_lines;
  133. int            scr_erase_center;
  134.  
  135. /*
  136. ==============
  137. SCR_CenterPrint
  138.  
  139. Called for important messages that should stay in the center of the screen
  140. for a few moments
  141. ==============
  142. */
  143. void SCR_CenterPrint (char *str)
  144. {
  145.     strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
  146.     scr_centertime_off = scr_centertime.value;
  147.     scr_centertime_start = cl.time;
  148.  
  149. // count the number of lines for centering
  150.     scr_center_lines = 1;
  151.     while (*str)
  152.     {
  153.         if (*str == '\n')
  154.             scr_center_lines++;
  155.         str++;
  156.     }
  157. }
  158.  
  159.  
  160. void SCR_DrawCenterString (void)
  161. {
  162.     char    *start;
  163.     int        l;
  164.     int        j;
  165.     int        x, y;
  166.     int        remaining;
  167.  
  168. // the finale prints the characters one at a time
  169.     if (cl.intermission)
  170.         remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
  171.     else
  172.         remaining = 9999;
  173.  
  174.     scr_erase_center = 0;
  175.     start = scr_centerstring;
  176.  
  177.     if (scr_center_lines <= 4)
  178.         y = vid.height*0.35;
  179.     else
  180.         y = 48;
  181.  
  182.     do    
  183.     {
  184.     // scan the width of the line
  185.         for (l=0 ; l<40 ; l++)
  186.             if (start[l] == '\n' || !start[l])
  187.                 break;
  188.         x = (vid.width - l*8)/2;
  189.         for (j=0 ; j<l ; j++, x+=8)
  190.         {
  191.             Draw_Character (x, y, start[j]);    
  192.             if (!remaining--)
  193.                 return;
  194.         }
  195.             
  196.         y += 8;
  197.  
  198.         while (*start && *start != '\n')
  199.             start++;
  200.  
  201.         if (!*start)
  202.             break;
  203.         start++;        // skip the \n
  204.     } while (1);
  205. }
  206.  
  207. void SCR_CheckDrawCenterString (void)
  208. {
  209.     scr_copytop = 1;
  210.     if (scr_center_lines > scr_erase_lines)
  211.         scr_erase_lines = scr_center_lines;
  212.  
  213.     scr_centertime_off -= host_frametime;
  214.     
  215.     if (scr_centertime_off <= 0 && !cl.intermission)
  216.         return;
  217.     if (key_dest != key_game)
  218.         return;
  219.  
  220.     SCR_DrawCenterString ();
  221. }
  222.  
  223. //=============================================================================
  224.  
  225. /*
  226. ====================
  227. CalcFov
  228. ====================
  229. */
  230. float CalcFov (float fov_x, float width, float height)
  231. {
  232.         float   a;
  233.         float   x;
  234.  
  235.         if (fov_x < 1 || fov_x > 179)
  236.                 Sys_Error ("Bad fov: %f", fov_x);
  237.  
  238.         x = width/tan(fov_x/360*M_PI);
  239.  
  240.         a = atan (height/x);
  241.  
  242.         a = a*360/M_PI;
  243.  
  244.         return a;
  245. }
  246.  
  247. /*
  248. =================
  249. SCR_CalcRefdef
  250.  
  251. Must be called whenever vid changes
  252. Internal use only
  253. =================
  254. */
  255. static void SCR_CalcRefdef (void)
  256. {
  257.     vrect_t        vrect;
  258.     float        size;
  259.     int        h;
  260.     qboolean        full = false;
  261.  
  262.  
  263.     scr_fullupdate = 0;        // force a background redraw
  264.     vid.recalc_refdef = 0;
  265.  
  266. // force the status bar to redraw
  267.     Sbar_Changed ();
  268.  
  269. //========================================
  270.     
  271. // bound viewsize
  272.     if (scr_viewsize.value < 30)
  273.         Cvar_Set ("viewsize","30");
  274.     if (scr_viewsize.value > 120)
  275.         Cvar_Set ("viewsize","120");
  276.  
  277. // bound field of view
  278.     if (scr_fov.value < 10)
  279.         Cvar_Set ("fov","10");
  280.     if (scr_fov.value > 170)
  281.         Cvar_Set ("fov","170");
  282.  
  283. // intermission is always full screen    
  284.     if (cl.intermission)
  285.         size = 120;
  286.     else
  287.         size = scr_viewsize.value;
  288.  
  289.     if (size >= 120)
  290.         sb_lines = 0;        // no status bar at all
  291.     else if (size >= 110)
  292.         sb_lines = 24;        // no inventory
  293.     else
  294.         sb_lines = 24+16+8;
  295.  
  296.     if (scr_viewsize.value >= 100.0) {
  297.         full = true;
  298.         size = 100.0;
  299.     } else
  300.         size = scr_viewsize.value;
  301.     if (cl.intermission)
  302.     {
  303.         full = true;
  304.         size = 100;
  305.         sb_lines = 0;
  306.     }
  307.     size /= 100.0;
  308.  
  309.     h = vid.height - sb_lines;
  310.  
  311.     r_refdef.vrect.width = vid.width * size;
  312.     if (r_refdef.vrect.width < 96)
  313.     {
  314.         size = 96.0 / r_refdef.vrect.width;
  315.         r_refdef.vrect.width = 96;    // min for icons
  316.     }
  317.  
  318.     r_refdef.vrect.height = vid.height * size;
  319.     if (r_refdef.vrect.height > vid.height - sb_lines)
  320.         r_refdef.vrect.height = vid.height - sb_lines;
  321.     if (r_refdef.vrect.height > vid.height)
  322.             r_refdef.vrect.height = vid.height;
  323.     r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2;
  324.     if (full)
  325.         r_refdef.vrect.y = 0;
  326.     else 
  327.         r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
  328.  
  329.     r_refdef.fov_x = scr_fov.value;
  330.     r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
  331.  
  332.     scr_vrect = r_refdef.vrect;
  333. }
  334.  
  335.  
  336. /*
  337. =================
  338. SCR_SizeUp_f
  339.  
  340. Keybinding command
  341. =================
  342. */
  343. void SCR_SizeUp_f (void)
  344. {
  345.     Cvar_SetValue ("viewsize",scr_viewsize.value+10);
  346.     vid.recalc_refdef = 1;
  347. }
  348.  
  349.  
  350. /*
  351. =================
  352. SCR_SizeDown_f
  353.  
  354. Keybinding command
  355. =================
  356. */
  357. void SCR_SizeDown_f (void)
  358. {
  359.     Cvar_SetValue ("viewsize",scr_viewsize.value-10);
  360.     vid.recalc_refdef = 1;
  361. }
  362.  
  363. //============================================================================
  364.  
  365. /*
  366. ==================
  367. SCR_Init
  368. ==================
  369. */
  370. void SCR_Init (void)
  371. {
  372.  
  373.     Cvar_RegisterVariable (&scr_fov);
  374.     Cvar_RegisterVariable (&scr_viewsize);
  375.     Cvar_RegisterVariable (&scr_conspeed);
  376.     Cvar_RegisterVariable (&scr_showram);
  377.     Cvar_RegisterVariable (&scr_showturtle);
  378.     Cvar_RegisterVariable (&scr_showpause);
  379.     Cvar_RegisterVariable (&scr_centertime);
  380.     Cvar_RegisterVariable (&scr_printspeed);
  381.     Cvar_RegisterVariable (&gl_triplebuffer);
  382.  
  383. //
  384. // register our commands
  385. //
  386.     Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
  387.     Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
  388.     Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
  389.  
  390.     scr_ram = Draw_PicFromWad ("ram");
  391.     scr_net = Draw_PicFromWad ("net");
  392.     scr_turtle = Draw_PicFromWad ("turtle");
  393.  
  394.     scr_initialized = true;
  395. }
  396.  
  397.  
  398.  
  399. /*
  400. ==============
  401. SCR_DrawRam
  402. ==============
  403. */
  404. void SCR_DrawRam (void)
  405. {
  406.     if (!scr_showram.value)
  407.         return;
  408.  
  409.     if (!r_cache_thrash)
  410.         return;
  411.  
  412.     Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
  413. }
  414.  
  415. /*
  416. ==============
  417. SCR_DrawTurtle
  418. ==============
  419. */
  420. void SCR_DrawTurtle (void)
  421. {
  422.     static int    count;
  423.     
  424.     if (!scr_showturtle.value)
  425.         return;
  426.  
  427.     if (host_frametime < 0.1)
  428.     {
  429.         count = 0;
  430.         return;
  431.     }
  432.  
  433.     count++;
  434.     if (count < 3)
  435.         return;
  436.  
  437.     Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle);
  438. }
  439.  
  440. /*
  441. ==============
  442. SCR_DrawNet
  443. ==============
  444. */
  445. void SCR_DrawNet (void)
  446. {
  447.     if (realtime - cl.last_received_message < 0.3)
  448.         return;
  449.     if (cls.demoplayback)
  450.         return;
  451.  
  452.     Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net);
  453. }
  454.  
  455. /*
  456. ==============
  457. DrawPause
  458. ==============
  459. */
  460. void SCR_DrawPause (void)
  461. {
  462.     qpic_t    *pic;
  463.  
  464.     if (!scr_showpause.value)        // turn off for screenshots
  465.         return;
  466.  
  467.     if (!cl.paused)
  468.         return;
  469.  
  470.     pic = Draw_CachePic ("gfx/pause.lmp");
  471.     Draw_Pic ( (vid.width - pic->width)/2, 
  472.         (vid.height - 48 - pic->height)/2, pic);
  473. }
  474.  
  475.  
  476.  
  477. /*
  478. ==============
  479. SCR_DrawLoading
  480. ==============
  481. */
  482. void SCR_DrawLoading (void)
  483. {
  484.     qpic_t    *pic;
  485.  
  486.     if (!scr_drawloading)
  487.         return;
  488.         
  489.     pic = Draw_CachePic ("gfx/loading.lmp");
  490.     Draw_Pic ( (vid.width - pic->width)/2, 
  491.         (vid.height - 48 - pic->height)/2, pic);
  492. }
  493.  
  494.  
  495.  
  496. //=============================================================================
  497.  
  498.  
  499. /*
  500. ==================
  501. SCR_SetUpToDrawConsole
  502. ==================
  503. */
  504. void SCR_SetUpToDrawConsole (void)
  505. {
  506.     Con_CheckResize ();
  507.     
  508.     if (scr_drawloading)
  509.         return;        // never a console with loading plaque
  510.         
  511. // decide on the height of the console
  512.     con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
  513.  
  514.     if (con_forcedup)
  515.     {
  516.         scr_conlines = vid.height;        // full screen
  517.         scr_con_current = scr_conlines;
  518.     }
  519.     else if (key_dest == key_console)
  520.         scr_conlines = vid.height/2;    // half screen
  521.     else
  522.         scr_conlines = 0;                // none visible
  523.     
  524.     if (scr_conlines < scr_con_current)
  525.     {
  526.         scr_con_current -= scr_conspeed.value*host_frametime;
  527.         if (scr_conlines > scr_con_current)
  528.             scr_con_current = scr_conlines;
  529.  
  530.     }
  531.     else if (scr_conlines > scr_con_current)
  532.     {
  533.         scr_con_current += scr_conspeed.value*host_frametime;
  534.         if (scr_conlines < scr_con_current)
  535.             scr_con_current = scr_conlines;
  536.     }
  537.  
  538.     if (clearconsole++ < vid.numpages)
  539.     {
  540.         Sbar_Changed ();
  541.     }
  542.     else if (clearnotify++ < vid.numpages)
  543.     {
  544.     }
  545.     else
  546.         con_notifylines = 0;
  547. }
  548.     
  549. /*
  550. ==================
  551. SCR_DrawConsole
  552. ==================
  553. */
  554. void SCR_DrawConsole (void)
  555. {
  556.     if (scr_con_current)
  557.     {
  558.         scr_copyeverything = 1;
  559.         Con_DrawConsole (scr_con_current, true);
  560.         clearconsole = 0;
  561.     }
  562.     else
  563.     {
  564.         if (key_dest == key_game || key_dest == key_message)
  565.             Con_DrawNotify ();    // only draw notify in game
  566.     }
  567. }
  568.  
  569.  
  570. /* 
  571. ============================================================================== 
  572.  
  573.                         SCREEN SHOTS 
  574.  
  575. ============================================================================== 
  576. */ 
  577.  
  578. typedef struct _TargaHeader {
  579.     unsigned char     id_length, colormap_type, image_type;
  580.     unsigned short    colormap_index, colormap_length;
  581.     unsigned char    colormap_size;
  582.     unsigned short    x_origin, y_origin, width, height;
  583.     unsigned char    pixel_size, attributes;
  584. } TargaHeader;
  585.  
  586.  
  587. /* 
  588. ================== 
  589. SCR_ScreenShot_f
  590. ================== 
  591. */  
  592. void SCR_ScreenShot_f (void) 
  593. {
  594.     byte        *buffer;
  595.     char        pcxname[80]; 
  596.     char        checkname[MAX_OSPATH];
  597.     int            i, c, temp;
  598. // 
  599. // find a file name to save it to 
  600. // 
  601.     strcpy(pcxname,"quake00.tga");
  602.         
  603.     for (i=0 ; i<=99 ; i++) 
  604.     { 
  605.         pcxname[5] = i/10 + '0'; 
  606.         pcxname[6] = i%10 + '0'; 
  607.         sprintf (checkname, "%s/%s", com_gamedir, pcxname);
  608.         if (Sys_FileTime(checkname) == -1)
  609.             break;    // file doesn't exist
  610.     } 
  611.     if (i==100) 
  612.     {
  613.         Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n"); 
  614.         return;
  615.      }
  616.  
  617.  
  618.     buffer = malloc(glwidth*glheight*3 + 18);
  619.     memset (buffer, 0, 18);
  620.     buffer[2] = 2;        // uncompressed type
  621.     buffer[12] = glwidth&255;
  622.     buffer[13] = glwidth>>8;
  623.     buffer[14] = glheight&255;
  624.     buffer[15] = glheight>>8;
  625.     buffer[16] = 24;    // pixel size
  626.  
  627.     glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); 
  628.  
  629.     // swap rgb to bgr
  630.     c = 18+glwidth*glheight*3;
  631.     for (i=18 ; i<c ; i+=3)
  632.     {
  633.         temp = buffer[i];
  634.         buffer[i] = buffer[i+2];
  635.         buffer[i+2] = temp;
  636.     }
  637.     COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 );
  638.  
  639.     free (buffer);
  640.     Con_Printf ("Wrote %s\n", pcxname);
  641.  
  642.  
  643. //=============================================================================
  644.  
  645.  
  646. /*
  647. ===============
  648. SCR_BeginLoadingPlaque
  649.  
  650. ================
  651. */
  652. void SCR_BeginLoadingPlaque (void)
  653. {
  654.     S_StopAllSounds (true);
  655.  
  656.     if (cls.state != ca_connected)
  657.         return;
  658.     if (cls.signon != SIGNONS)
  659.         return;
  660.     
  661. // redraw with no console and the loading plaque
  662.     Con_ClearNotify ();
  663.     scr_centertime_off = 0;
  664.     scr_con_current = 0;
  665.  
  666.     scr_drawloading = true;
  667.     scr_fullupdate = 0;
  668.     Sbar_Changed ();
  669.     SCR_UpdateScreen ();
  670.     scr_drawloading = false;
  671.  
  672.     scr_disabled_for_loading = true;
  673.     scr_disabled_time = realtime;
  674.     scr_fullupdate = 0;
  675. }
  676.  
  677. /*
  678. ===============
  679. SCR_EndLoadingPlaque
  680.  
  681. ================
  682. */
  683. void SCR_EndLoadingPlaque (void)
  684. {
  685.     scr_disabled_for_loading = false;
  686.     scr_fullupdate = 0;
  687.     Con_ClearNotify ();
  688. }
  689.  
  690. //=============================================================================
  691.  
  692. char    *scr_notifystring;
  693. qboolean    scr_drawdialog;
  694.  
  695. void SCR_DrawNotifyString (void)
  696. {
  697.     char    *start;
  698.     int        l;
  699.     int        j;
  700.     int        x, y;
  701.  
  702.     start = scr_notifystring;
  703.  
  704.     y = vid.height*0.35;
  705.  
  706.     do    
  707.     {
  708.     // scan the width of the line
  709.         for (l=0 ; l<40 ; l++)
  710.             if (start[l] == '\n' || !start[l])
  711.                 break;
  712.         x = (vid.width - l*8)/2;
  713.         for (j=0 ; j<l ; j++, x+=8)
  714.             Draw_Character (x, y, start[j]);    
  715.             
  716.         y += 8;
  717.  
  718.         while (*start && *start != '\n')
  719.             start++;
  720.  
  721.         if (!*start)
  722.             break;
  723.         start++;        // skip the \n
  724.     } while (1);
  725. }
  726.  
  727. /*
  728. ==================
  729. SCR_ModalMessage
  730.  
  731. Displays a text string in the center of the screen and waits for a Y or N
  732. keypress.  
  733. ==================
  734. */
  735. int SCR_ModalMessage (char *text)
  736. {
  737.     if (cls.state == ca_dedicated)
  738.         return true;
  739.  
  740.     scr_notifystring = text;
  741.  
  742. // draw a fresh screen
  743.     scr_fullupdate = 0;
  744.     scr_drawdialog = true;
  745.     SCR_UpdateScreen ();
  746.     scr_drawdialog = false;
  747.     
  748.     S_ClearBuffer ();        // so dma doesn't loop current sound
  749.  
  750.     do
  751.     {
  752.         key_count = -1;        // wait for a key down and up
  753.         Sys_SendKeyEvents ();
  754.     } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
  755.  
  756.     scr_fullupdate = 0;
  757.     SCR_UpdateScreen ();
  758.  
  759.     return key_lastpress == 'y';
  760. }
  761.  
  762.  
  763. //=============================================================================
  764.  
  765. /*
  766. ===============
  767. SCR_BringDownConsole
  768.  
  769. Brings the console down and fades the palettes back to normal
  770. ================
  771. */
  772. void SCR_BringDownConsole (void)
  773. {
  774.     int        i;
  775.     
  776.     scr_centertime_off = 0;
  777.     
  778.     for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
  779.         SCR_UpdateScreen ();
  780.  
  781.     cl.cshifts[0].percent = 0;        // no area contents palette on next frame
  782.     VID_SetPalette (host_basepal);
  783. }
  784.  
  785. void SCR_TileClear (void)
  786. {
  787.     if (r_refdef.vrect.x > 0) {
  788.         // left
  789.         Draw_TileClear (0, 0, r_refdef.vrect.x, vid.height - sb_lines);
  790.         // right
  791.         Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, 0, 
  792.             vid.width - r_refdef.vrect.x + r_refdef.vrect.width, 
  793.             vid.height - sb_lines);
  794.     }
  795.     if (r_refdef.vrect.y > 0) {
  796.         // top
  797.         Draw_TileClear (r_refdef.vrect.x, 0, 
  798.             r_refdef.vrect.x + r_refdef.vrect.width, 
  799.             r_refdef.vrect.y);
  800.         // bottom
  801.         Draw_TileClear (r_refdef.vrect.x,
  802.             r_refdef.vrect.y + r_refdef.vrect.height, 
  803.             r_refdef.vrect.width, 
  804.             vid.height - sb_lines - 
  805.             (r_refdef.vrect.height + r_refdef.vrect.y));
  806.     }
  807. }
  808.  
  809. /*
  810. ==================
  811. SCR_UpdateScreen
  812.  
  813. This is called every frame, and can also be called explicitly to flush
  814. text to the screen.
  815.  
  816. WARNING: be very careful calling this from elsewhere, because the refresh
  817. needs almost the entire 256k of stack space!
  818. ==================
  819. */
  820. void SCR_UpdateScreen (void)
  821. {
  822.     static float    oldscr_viewsize;
  823.     vrect_t        vrect;
  824.  
  825.     if (block_drawing)
  826.         return;
  827.  
  828.     vid.numpages = 2 + gl_triplebuffer.value;
  829.  
  830.     scr_copytop = 0;
  831.     scr_copyeverything = 0;
  832.  
  833.     if (scr_disabled_for_loading)
  834.     {
  835.         if (realtime - scr_disabled_time > 60)
  836.         {
  837.             scr_disabled_for_loading = false;
  838.             Con_Printf ("load failed.\n");
  839.         }
  840.         else
  841.             return;
  842.     }
  843.  
  844.     if (!scr_initialized || !con_initialized)
  845.         return;                // not initialized yet
  846.  
  847.  
  848.     GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
  849.     
  850.     //
  851.     // determine size of refresh window
  852.     //
  853.     if (oldfov != scr_fov.value)
  854.     {
  855.         oldfov = scr_fov.value;
  856.         vid.recalc_refdef = true;
  857.     }
  858.  
  859.     if (oldscreensize != scr_viewsize.value)
  860.     {
  861.         oldscreensize = scr_viewsize.value;
  862.         vid.recalc_refdef = true;
  863.     }
  864.  
  865.     if (vid.recalc_refdef)
  866.         SCR_CalcRefdef ();
  867.  
  868. //
  869. // do 3D refresh drawing, and then update the screen
  870. //
  871.     SCR_SetUpToDrawConsole ();
  872.     
  873.     V_RenderView ();
  874.  
  875.     GL_Set2D ();
  876.  
  877.     //
  878.     // draw any areas not covered by the refresh
  879.     //
  880.     SCR_TileClear ();
  881.  
  882.     if (scr_drawdialog)
  883.     {
  884.         Sbar_Draw ();
  885.         Draw_FadeScreen ();
  886.         SCR_DrawNotifyString ();
  887.         scr_copyeverything = true;
  888.     }
  889.     else if (scr_drawloading)
  890.     {
  891.         SCR_DrawLoading ();
  892.         Sbar_Draw ();
  893.     }
  894.     else if (cl.intermission == 1 && key_dest == key_game)
  895.     {
  896.         Sbar_IntermissionOverlay ();
  897.     }
  898.     else if (cl.intermission == 2 && key_dest == key_game)
  899.     {
  900.         Sbar_FinaleOverlay ();
  901.         SCR_CheckDrawCenterString ();
  902.     }
  903.     else
  904.     {
  905.         if (crosshair.value)
  906.             Draw_Character (scr_vrect.x + scr_vrect.width/2, scr_vrect.y + scr_vrect.height/2, '+');
  907.         
  908.         SCR_DrawRam ();
  909.         SCR_DrawNet ();
  910.         SCR_DrawTurtle ();
  911.         SCR_DrawPause ();
  912.         SCR_CheckDrawCenterString ();
  913.         Sbar_Draw ();
  914.         SCR_DrawConsole ();    
  915.         M_Draw ();
  916.     }
  917.  
  918.     V_UpdatePalette ();
  919.  
  920.     GL_EndRendering ();
  921. }
  922.  
  923.